package cn.good.yan.b9;

import java.util.concurrent.*;

/**
 * b9 多綫程
 *
 * @author shengren.yan
 * @create 2023-07-23
 */
public class Test {

    public static void main(String[] args) throws Exception {
        Test t = new Test();
//         操作1 ：启动10个线程
//        for (int i = 0; i < 10; i++) {
//            t.t2("线程" + i);
//        }

//        t.t5("s");
        t.t6("s");
    }

    /**
     * 1 基础
     * 程序：特定的任务
     * 进程：程序一次执行过程，如：微信语音，播放器播放音乐
     * 线程：一个进程至少有一个线程
     * 并行: 多个任务同时执行
     * 并发：多个指令同时抢占同一个资源
     * 线程的状态：新建 - 就绪 - 运行 - 等待 （无限等待、等待某个时间） -死亡
     */
    public void t1() throws Exception {
        // 1. 睡眠 单位毫秒
        Thread.sleep(3000);
        // 2. 当前线程礼让一下，释放CPU执行权
        Thread.yield();
        // 3. join 当一个a线程调用b线程，a线程阻塞状态，等b线程执行完，再执行a
        // 4. isAlive  当前线程是否存活
    }

    /**
     * 2 Thread 创建线程
     *   创建一个线程的方法
     */
    public void t2(String name) throws Exception {
        // name 线程名
        new Thread(name) {
            @Override
            public void run() {
                System.out.println("匿名内部类创建线程方式1...");
                System.out.println(Thread.currentThread().getName() + "线程名字");
                // 这里写循环 是频繁操作
            };
        }.start();
    }

    /**
     * 3 Runnable 创建线程
     */
    public void t3() throws Exception {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类创建线程方式2...");
            }
        }).start();
    }

    /**
     * 4 lambda 创建线程
     * @param s 线程名
     */
    public Thread t4(String s) throws Exception {
        Thread thread = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "线程名字：" + s);
//            System.out.println("使用lambda表示创建线程");
        });
        return thread;
    }


    /**
     * 5 Callable 创建线程 （有返回值）
     * @param s 线程名
     */
    public void t5(String s) throws Exception {
        FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>) () -> {
            //这里相当于call方法执行体。
            int i = 0;
            for (i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "=====" + i);
            }
            return i;
        });

        for (int i = 0; i < 10; i++) {
            // 主线程
            System.out.println(Thread.currentThread().getName() + "=======" + i);
            if (i == 0) {
                // 创建一个线程，并start启动它。(创建的线程)
                Thread t1 = new Thread(task, "我是fu线程");
                t1.start();
            }
        }

        // 得到返回值，注意这个必须要有显示抛出异常
        try {
            System.out.println("子线程的返回值" + task.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * t6 线程池，创建线程
     *
     * @throws Exception 异常
     */
    public void t6(String s) throws Exception {
        // 创建线程池 （10个线程）
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor executor = (ThreadPoolExecutor) service;
        // 设置最大线程数
        executor.setMaximumPoolSize(50);
        executor.execute(new Thread(() -> {
            // 模拟复杂的并发
            for (int i = 0; i < 1000; i++) {
                System.out.println(Thread.currentThread().getName() + "线程名字：" + i);
            }
        }));
        executor.execute(new Thread(() -> {
            // 模拟复杂的并发
            for (int i = 0; i < 100; i++) {
                if(i%2!=0){
                    System.out.println(Thread.currentThread().getName() + "线程名字hh：" + i);
                }
            }
        }));
        // 关闭线程池
        executor.shutdown();
    }

}
